﻿using System;
using System.Collections.Generic;
using OhioState.Graphics;
using OhioState.Graphics.Proxy;
using OhioState.Graphics.OpenGL;
using OhioState.Math;
using OhioState.Physics;

namespace OhioState.Graphics.OpenGL
{
    public class GraphicsGeneratorGL : GraphicsGenerator
    {
        public GraphicsGeneratorGL()
        {
        }

        public Object getObject(Type type, IList<object> args)
        {
            if (type == typeof(AxesPlaneGL))
            {
                return new AxesPlaneGL((List<Vector3>)args[0], (List<Vector3>)args[1], (List<Vector3>)args[2]);
            }
            else if (type == typeof(BoxBoundaryGL))
            {
                return new BoxBoundaryGL((BoundingBox)args[0]);
            }
            else if (type == typeof(BoxOutlineGL))
            {
                return new BoxOutlineGL((BoundingBox)args[0]);
            }
            else if (type == typeof(ClipPlaneGL))
            {
                return new ClipPlaneGL();
            }
            else if(type == typeof(DepthBufferGL))
            {
                return new DepthBufferGL((int)args[0], (int)args[1], (bool)args[2]);
            }
            else if(type == typeof(FrameBufferObjectGL))
            {
                //depending on the arg types, use one of four constructors

                if(args.Count == 2 && args[0] is ITexture && args[1] is FrameBufferClear)
                {
                    return new FrameBufferObjectGL((ITexture)args[0], (FrameBufferClear)args[1]);
                }
                else if (args.Count == 2 && args[0] is ICollection<ITexture> && args[1] is FrameBufferClear)
                {
                    return new FrameBufferObjectGL((ICollection<ITexture>)args[0], (FrameBufferClear)args[1]);
                }
                else if (args.Count == 3 && args[0] is ITexture && args[1] is IDepthBuffer && args[2] is FrameBufferClear)
                {
                    return new FrameBufferObjectGL((ITexture)args[0], (IDepthBuffer)args[1], (FrameBufferClear)args[2]);
                }
                else
                {
                    return new FrameBufferObjectGL((ICollection<ITexture>)args[0], (IDepthBuffer)args[1], (FrameBufferClear)args[2]);
                }
                return null;
            }
            else if(type == typeof(LayerGL))
            {
                return new LayerGL();
            }
            else if(type == typeof(MaterialGL))
            {
                return new MaterialGL();
            }
            else if(type == typeof(QuadList))
            {
                //two possible constructors
                if (args == null)
                    return new QuadList();
                else
                    return new QuadList((int)args[0]);
            }
            else if(type == typeof(RenderableTexture2DGL2))
            {
                return new RenderableTexture2DGL2((ITexture)args[0]);
            }
            else if(type == typeof(RigidBodyGL))
            {
                return new RigidBodyGL((RigidBody)args[0]);
            }
            else if(type == typeof(ShaderProgramGL))
            {
                return new ShaderProgramGL();
            }
            //else if(type == typeof(ShaderRoutineGL))
            //{
            //    return new ShaderRoutineGL();
            //}
            else if(type == typeof(SlicePlaneGL))
            {
                return new SlicePlaneGL((BoundingBox)args[0], (Vector3)args[1], (Vector3)args[2]);
            }
            else if(type == typeof(SphereGL))
            {
                return new SphereGL((float)args[0]);
            }
            else if (type == typeof(Texture2DGL))
            {
                return new Texture2DGL((int)args[0], (int)args[1], (TexelFormat)args[2]);
            }
            else if (type == typeof(Texture3DGL))
            {
                return new Texture3DGL((int)args[0], (int)args[1], (int)args[2], (TexelFormat)args[3]);
            }
            else if (type == typeof(ViewGL))
            {
                return new ViewGL();
            }

            return null;
        }
    }
}
